package com.sz.callPhoneTest.call_phone_test;

import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.GestureDescription;
import android.annotation.TargetApi;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Path;
import android.graphics.Rect;
import android.media.AudioManager;
import android.media.MediaRecorder;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.provider.Settings;
import android.telecom.TelecomManager;
import android.telephony.PhoneStateListener;
import android.telephony.PreciseDataConnectionState;
import android.telephony.TelephonyCallback;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

import com.android.internal.telephony.ITelephony;
import com.google.gson.Gson;
import com.squareup.okhttp.Request;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.StringCallback;

import org.greenrobot.eventbus.EventBus;
import org.java_websocket.drafts.Draft_6455;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

public class CallPhoneService extends AccessibilityService {
    private static final String TAG = "RecorderService";
    /**
     * 音频录制
     */
    private MediaRecorder recorder;
    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    /**
     * 监听拨号广播，以便获取用户拨出的电话号码
     */
    private OutCallReceiver outCallReceiver;
    private IntentFilter intentFilter;
    /**
     * 网络状态改变广播，当网络畅通的状态下，把用户未上传的录音文件都上传掉
     */
    private NetworkConnectChangedReceiver networkConnectChangedReceiver;
    private IntentFilter intentFilter2;

    private String currentCallNum = "";
    private String currentCallUUID = "";
    /**
     * 区分来电和去电
     */
    private int previousStats = 0;
    /**
     * 当前正在录制的文件
     */
    private String currentFile = "";
    /**
     * 保存未上传的录音文件
     */
    private SharedPreferences unUploadFileSharedPreferences;
    private String dirPath = "";
    private boolean isRecording = false;
    private WebSocketClient client;
    private NotificationManager mManager;
    private ExecutorService executorService;
    private Timer heartbeatTimer;
    private int cid;
    private String code;
    private long callTime = 0;
    private int hangupState = 0;
//    private FileCheckThread fileCheckThread;
    private File[] oldFileArray;
    private boolean hasSendState = true;
    private boolean hasSendHangUpState = true;
    private boolean hasRegistered = false;
    private int mWidth;
    private int mHeight;

    private long currentClickTime = 0;
    private static final String[] STATE_ARR = {"拨号", "震铃", "00:00", "00:01", "挂断", "结束"};
    private final Handler handler = new Handler();
    private final Runnable sendHangupStateTask = new Runnable() {
        @Override
        public void run() {
            Log.i(TAG, "执行发送挂断状态-Runnable");
            sendHangUpState();
        }
    };

    @Override
    protected void onServiceConnected() {
        Log.i(TAG, "onServiceConnected()");
    }

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        Log.i(TAG, "onAccessibilityEvent() -> eventType:" + event.getEventType());
        String packageName = event.getPackageName().toString();
        if (packageName.equals("com.android.incallui")) {

            handler.removeCallbacks(sendHangupStateTask);
            handler.postDelayed(sendHangupStateTask, 2500);

            if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {
                //找电话状态节点
                List<AccessibilityNodeInfo> nodeInfos = findStateInfoAccessibilityNodeInfo();
                if (nodeInfos == null || nodeInfos.isEmpty()) {
                    Log.i("test", "onAccessibilityEvent() -> 没有找到电话状态节点");
                    return;
                }
                Log.i("test", "onAccessibilityEvent() -> 找到电话状态节点");
                AccessibilityNodeInfo nodeInfo = nodeInfos.get(0);
                if (nodeInfo.getText() == null) {
                    return;
                }
                nodeInfo.refresh();
                String state = nodeInfo.getText().toString();
                if (TextUtils.isEmpty(state)) {
                    Log.i("test", "onAccessibilityEvent() -> 电话状态是空的");
                    return;
                }
                Log.i("test", "onAccessibilityEvent() -> 电话状态是："+state);
                if (state.contains("拨号")){

                } else if(state.contains("震铃")) {

                } else if(state.contains("00:00") || state.contains("00:01")) {
                    if (!hasSendState && !TextUtils.isEmpty(currentCallUUID)) {
                        hasSendState = true;
//                                CallPhoneStateModel stateModel = new CallPhoneStateModel(
//                                        "callstate", 2, "1111-2222-3333");
                        CallPhoneStateModel stateModel = new CallPhoneStateModel("callstate",
                                2, currentCallUUID);
                        Gson gson = new Gson();
                        String text = gson.toJson(stateModel);
                        Log.d(TAG, "发送电话状态："+text);
                        client.send(text);
                    }
                } else if (state.contains("挂断") || state.contains("挂机") || state.contains("结束")) {
                    if (!hasSendHangUpState && !TextUtils.isEmpty(currentCallUUID)) {
                        hasSendHangUpState = true;

                        if (oldFileArray != null && oldFileArray.length != getRecordFileArray().length) {
                            uploadFileToServer();
                        }

                        executorService.execute(new Runnable() {
                            @Override
                            public void run() {
//                        CallPhoneStateModel stateModel = new CallPhoneStateModel("callstate",
//                                hangupState == 1 ? 5 : 4, "1111-2222-3333");
                                CallPhoneStateModel stateModel = new CallPhoneStateModel("callstate",
                                        hangupState == 1 ? 5 : 4, currentCallUUID);
                                Gson gson = new Gson();
                                String text = gson.toJson(stateModel);
                                Log.d(TAG, "发送电话状态："+text);
                                client.send(text);

                                currentCallUUID = null;
                                hangupState = 0;
                            }
                        });
                    }
                }

                if (currentClickTime == 0) {
                    currentClickTime = System.currentTimeMillis();
                }

                long endTime = System.currentTimeMillis();
                long elapsedTime = endTime - currentClickTime;
                if (elapsedTime > 5000) {
                    Log.i("test", "onAccessibilityEvent() -> 大于5s执行屏幕常亮点击操作...");
                    currentClickTime = 0;
                    autoClickByGesture(mWidth-20, mHeight-20);
                }
            }
        }
    }

    private void sendHangUpState() {
        if (!hasSendHangUpState && !TextUtils.isEmpty(currentCallUUID)) {
            hasSendHangUpState = true;

            if (oldFileArray != null && oldFileArray.length != getRecordFileArray().length) {
                uploadFileToServer();
            }

            executorService.execute(new Runnable() {
                @Override
                public void run() {
//                        CallPhoneStateModel stateModel = new CallPhoneStateModel("callstate",
//                                hangupState == 1 ? 5 : 4, "1111-2222-3333");
                    CallPhoneStateModel stateModel = new CallPhoneStateModel("callstate",
                            hangupState == 1 ? 5 : 4, currentCallUUID);
                    Gson gson = new Gson();
                    String text = gson.toJson(stateModel);
                    Log.d(TAG, "发送电话状态："+text);
                    client.send(text);

                    currentCallUUID = null;
                    hangupState = 0;
                }
            });
        }
    }


    private List<AccessibilityNodeInfo> findStateInfoAccessibilityNodeInfo() {
        AccessibilityNodeInfo rootNodeInfo = getRootInActiveWindow();
        if (rootNodeInfo == null) {
            return null;
        }

        //找不到在通过text找
        for (int i = 0; i < STATE_ARR.length; i++) {
            List<AccessibilityNodeInfo> result = rootNodeInfo.findAccessibilityNodeInfosByText(STATE_ARR[i]);
            if (result != null && !result.isEmpty()) {
                return result;
            }
        }

        return null;
    }

    interface AccessibilityNodeInfoCallback2{
        void onAccessibilityNodeInfoCallback2(AccessibilityNodeInfo nodeInfo);
    }

    private void startFindNodeInfoByDescription(String description, AccessibilityNodeInfoCallback2 callback2) {
        AccessibilityNodeInfo rootNode = getRootInActiveWindow();
        if (rootNode != null) {
            findAllNodeInfo(rootNode, description, callback2);
        }
    }


    private void findAllNodeInfo(AccessibilityNodeInfo nodeInfo, String description,
                                 AccessibilityNodeInfoCallback2 callback2) {
        if (nodeInfo == null) {
            return;
        }
//        Log.e(TAG, "findAllNodeInfo() -> InfoClassName: " + nodeInfo.getClassName());
//        Log.e(TAG, "findAllNodeInfo() -> InfoText: " + nodeInfo.getText());
//        Log.e(TAG, "findAllNodeInfo() -> InfoPkgName: " + nodeInfo.getPackageName());
//        Log.e(TAG, "findAllNodeInfo() -> InfoViewId: " + nodeInfo.getViewIdResourceName());
//        Log.e(TAG, "findAllNodeInfo() -> InfoContentDescription: " + nodeInfo.getContentDescription());
        if (nodeInfo.getContentDescription() != null && nodeInfo.getContentDescription()
                .toString().contains(description)) {
            // 打印出找到的AccessibilityNodeInfo的坐标点
//            Rect rect = new Rect();
//            nodeInfo.getBoundsInScreen(rect);
//            Log.d(TAG, "findAllNodeInfo() -> 坐标点：" + rect.centerX() + ", " + rect.centerY());
//            Log.d(TAG, "findAllNodeInfo() -> 坐标点：" + rect.centerX() + ", " + rect.centerY());
            callback2.onAccessibilityNodeInfoCallback2(nodeInfo);
        }

        if (nodeInfo.getText() != null && nodeInfo.getText()
                .toString().contains(description)) {
            // 打印出找到的AccessibilityNodeInfo的坐标点
//            Rect rect = new Rect();
//            nodeInfo.getBoundsInScreen(rect);
//            Log.d(TAG, "findAllNodeInfo() -> 坐标点：" + rect.centerX() + ", " + rect.centerY());
//            Log.d(TAG, "findAllNodeInfo() -> 坐标点：" + rect.centerX() + ", " + rect.centerY());
            callback2.onAccessibilityNodeInfoCallback2(nodeInfo);
        }
        // 递归遍历子节点
        if (nodeInfo.getChildCount() > 0) {
            for (int i = 0; i < nodeInfo.getChildCount(); i++) {
                findAllNodeInfo(nodeInfo.getChild(i), description, callback2);
            }
        }
    }

    private void autoClickHangup() {
        AccessibilityNodeInfo nodeInfo = findAccessibilityNodeInfosByViewIdAndDescription(
                getString(R.string.end_button), "挂");
        if (nodeInfo != null) {
            Rect rect = new Rect();
            nodeInfo.getBoundsInScreen(rect);
            autoClickByGesture(rect.centerX(), rect.centerY());
            if (nodeInfo.getContentDescription() != null){
                Log.i(TAG, "autoClickHangup() -> 111找到挂断节点，开始自动点击: x="+rect.centerX()
                        +",y="+rect.centerY()+",des="+nodeInfo.getContentDescription().toString());
            } else {
                Log.i(TAG, "autoClickHangup() -> 111找到挂断节点，开始自动点击: x="+rect.centerX()
                        +",y="+rect.centerY());
            }
            return;
        }

        startFindNodeInfoByDescription("挂", new AccessibilityNodeInfoCallback2() {
            @Override
            public void onAccessibilityNodeInfoCallback2(AccessibilityNodeInfo nodeInfo) {
                if (nodeInfo != null) {
                    Rect rect = new Rect();
                    nodeInfo.getBoundsInScreen(rect);
                    autoClickByGesture(rect.centerX(), rect.centerY());
                    if (nodeInfo.getContentDescription() != null){
                        Log.i(TAG, "autoClickHangup() -> 222找到挂断节点，开始自动点击: x="+rect.centerX()
                                +",y="+rect.centerY()+",des="+nodeInfo.getContentDescription().toString());
                    } else {
                        Log.i(TAG, "autoClickHangup() -> 222找到挂断节点，开始自动点击: x="+rect.centerX()
                                +",y="+rect.centerY());
                    }
                }
            }
        });

    }

    private AccessibilityNodeInfo findAccessibilityNodeInfosByViewIdAndDescription(String id, String description) {
        AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
        if (nodeInfo == null) {
            return null;
        }
        List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByViewId(id);
        if (list == null || list.isEmpty()) {
            return null;
        }
        for (AccessibilityNodeInfo n: list) {
            if (n.getContentDescription() != null && n.getContentDescription().toString().contains(description)) {
                return n;
            }

            if (n.getText() != null && n.getText().toString().contains(description)) {
                return n;
            }
        }
        return null;
    }

    private boolean performClickNodeInfo(AccessibilityNodeInfo nodeInfo) {
        if (nodeInfo != null) {
            if (nodeInfo.isClickable()) {
                nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                return true;
            } else {
                AccessibilityNodeInfo parent = nodeInfo.getParent();
                if (parent != null) {
                    boolean isParentClickSuccess = performClickNodeInfo(parent);
                    parent.recycle();
                    return isParentClickSuccess;
                }
            }
        }
        return false;
    }

    private void autoClickByGesture(float x, float y) {
        Log.i(TAG, "autoClickByGesture() -> 开始自动点击: x="+x+",y="+y);
        GestureDescription.Builder builder = new GestureDescription.Builder();
        Path path = new Path();
        path.moveTo(x, y);
        path.lineTo(x, y);
        builder.addStroke(new GestureDescription.StrokeDescription(path, 0, 1));
        GestureDescription gestureDescription = builder.build();
        dispatchGesture(gestureDescription, new GestureResultCallback() {
            @Override
            public void onCompleted(GestureDescription gestureDescription) {
                super.onCompleted(gestureDescription);
                Log.i(TAG, "autoClickByGesture() -> 自动点击成功");

            }

            @Override
            public void onCancelled(GestureDescription gestureDescription) {
                super.onCancelled(gestureDescription);
                Log.i(TAG, "autoClickByGesture() -> 自动点击失败");
            }
        }, null);
    }

    private void autoClickById() {
        Log.i(TAG, "autoClickById() -> 开始自动点击");
        AccessibilityNodeInfo nodeInfo = findAccessibilityNodeInfosByViewIdAndDescription(
                getString(R.string.end_button), "挂");
        if (nodeInfo != null) {
            Log.i("test", "autoClickById() -> 找到挂断电话节点");
            boolean isSuccess = performClickNodeInfo(nodeInfo);
            if (isSuccess) {
                Log.i("test", "autoClickById() -> 挂断电话成功");
            }else{
                Log.i("test", "autoClickById() -> 挂断电话失败");
            }
        } else {
            Log.i("test", "autoClickById() -> 没有找到挂断电话节点");
        }
    }

    @Override
    public void onInterrupt() {
        Log.i(TAG, "onInterrupt()");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        int action = intent.getIntExtra("action", -1);
        this.cid = intent.getIntExtra("cid", -1);
        this.code = intent.getStringExtra("code");

        if (!hasRegistered) {
            hasRegistered = true;
            TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                tm.registerTelephonyCallback(getApplicationContext().getMainExecutor(),
                        new MyTelephonyCallback());
                Log.i(TAG, "device >=31");
            } else {
                Log.i(TAG, "device <31");
                // 监听电话状态
                tm.listen(new MyPhoneStateListener(), PhoneStateListener.LISTEN_CALL_STATE);
            }
        }


        if (action == 401) {
            if (client == null) {
                initWebSocket();
            }

            if (client.isOpen()) {
                EventBus.getDefault().post(new WebSocketClientEvent(WebSocketClientEvent.CONNECTED));
            } else {
                try {
                    //连接时可以使用connect()方法或connectBlocking()方法，
                    // 建议使用connectBlocking()方法，
                    // connectBlocking多出一个等待操作，会先连接再发送。
                    EventBus.getDefault().post(new WebSocketClientEvent(WebSocketClientEvent.CONNECTING));

                    if (client.isClosed()) {
                        client.reconnectBlocking();
                    } else {
                        client.connectBlocking();
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }


            if(heartbeatTimer == null) {
                heartbeatTimer = new Timer();
            }

            heartbeatTimer.schedule(new TimerTask() {
                @Override
                public void run() {
                    Log.e(TAG, "==定时器存在==");
                    if (client == null) {
                        return;
                    }
                    if (client.isClosed()) {
                        try {
                            Log.e(TAG, "==重连中==");
                            EventBus.getDefault().post(new WebSocketClientEvent(
                                    WebSocketClientEvent.CONNECTING));

                            if (client.isClosed()) {
                                client.reconnectBlocking();
                            } else {
                                client.connectBlocking();
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    } else {
                        Log.e(TAG, "==发送心跳==");
                        client.sendPing();
                    }
                }
            }, 0, 30000);


        } else if (action == 402) {
            client.close();
            client = null;

            if (heartbeatTimer != null) {
                heartbeatTimer.cancel();
                heartbeatTimer = null;
            }

            currentCallUUID = null;
        } else if (action == 403) {
            try {
                Intent i = new Intent(Intent.ACTION_CALL,
                        Uri.parse("tel:10010"));
                i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(i);
            }catch (Exception e){
                e.printStackTrace();
            }
        } else if (action == 404) {
            hangup();
        } else if (action == 405) {
//            startRecording("10010");
        } else if (action == 406) {
//            stopRecording();
        } else if (action == 407) {

        }
        return START_REDELIVER_INTENT;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        startForeground((int) System.currentTimeMillis(),
                getNotification("软电话", "软电话正在后台运行"));

        outCallReceiver = new OutCallReceiver();
        intentFilter = new IntentFilter();
        //设置拨号广播过滤
        intentFilter.addAction("android.intent.action.NEW_OUTGOING_CALL");
        registerReceiver(outCallReceiver, intentFilter);
        //注册拨号广播接收器
        networkConnectChangedReceiver = new NetworkConnectChangedReceiver();
        intentFilter2 = new IntentFilter();
        //设置网络状态改变广播过滤
        intentFilter2.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        intentFilter2.addAction("android.net.wifi.WIFI_STATE_CHANGED");
        intentFilter2.addAction("android.net.wifi.STATE_CHANGE");
        //注册网络状态改变广播接收器
        registerReceiver(networkConnectChangedReceiver, intentFilter2);
        unUploadFileSharedPreferences = getSharedPreferences("un_upload_file", Context.MODE_PRIVATE);
        dirPath = getExternalFilesDir(null).getAbsolutePath() + "/call_phone/";
        executorService = Executors.newSingleThreadExecutor();
        WindowManager manager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        //获取屏幕参数
        DisplayMetrics metrics = new DisplayMetrics();
        manager.getDefaultDisplay().getMetrics(metrics);
        mWidth = metrics.widthPixels;
        mHeight = metrics.heightPixels;
        Log.i(TAG, "存储录音的路径为："+ dirPath);
        Log.i(TAG, "当前的手机品牌是："+ Build.BRAND);
        Log.i(TAG, "当前的手机品牌是："+ RomUtils.getRomInfo().getName());
        Log.i(TAG, "当前的手机宽是："+ mWidth);
        Log.i(TAG, "当前的手机高是："+ mHeight);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (outCallReceiver != null) {
            unregisterReceiver(outCallReceiver);
        }
        if (networkConnectChangedReceiver != null) {
            unregisterReceiver(networkConnectChangedReceiver);
        }

        client.close();
        client = null;

//        if (fileCheckThread != null) {
//            fileCheckThread.setFlag(false);
//            fileCheckThread = null;
//        }

        executorService.shutdownNow();
        executorService = null;

        if (heartbeatTimer != null) {
            heartbeatTimer.cancel();
            heartbeatTimer = null;
        }

        currentCallUUID = null;
    }

    private void initWebSocket() {
        //https://blog.csdn.net/weixin_42046829/article/details/108501607
        //websocket协议地址大致是这样的: ws:// ip地址 : 端口号
        client = new WebSocketClient(URI.create(Constants.WEB_SOCKET_URL + "?code="+code+"&cid="+cid),
                new Draft_6455()) {
            @Override
            public void onOpen(ServerHandshake handshake) {
                Log.e(TAG, "连接成功");
                EventBus.getDefault().post(new WebSocketClientEvent(WebSocketClientEvent.CONNECTED));
            }

            @Override
            public void onMessage(String message) {
                Log.e(TAG, "收到消息:"+message);
                if (message == null || message.isEmpty()) {
                    return;
                }

                try {
                    CallPhoneEventModel eventModel = new Gson().fromJson(message,
                            CallPhoneEventModel.class);
                    if (eventModel.getMsgType().equals("callphone")) {
                        currentCallNum = eventModel.getPhoneNo();
                        currentCallUUID = eventModel.getUuid();

                        hasSendState = false;
                        hasSendHangUpState = false;
                        oldFileArray = getRecordFileArray();

//                        fileCheckThread = new FileCheckThread();
//                        fileCheckThread.addFileChangedCallback((originalFileArray, recordFileArray) -> {
////                                CallPhoneStateModel stateModel = new CallPhoneStateModel(
////                                        "callstate", 2, "1111-2222-3333");
//                            CallPhoneStateModel stateModel = new CallPhoneStateModel("callstate",
//                                    2, currentCallUUID);
//                            Gson gson = new Gson();
//                            String text = gson.toJson(stateModel);
//                            Log.d(TAG, "发送电话状态："+text);
//                            client.send(text);
//                        });
//                        fileCheckThread.start();

                        executorService.execute(new Runnable() {
                            @Override
                            public void run() {
//                                CallPhoneStateModel stateModel = new CallPhoneStateModel(
//                                        "callstate", 1, "1111-2222-3333");
                                CallPhoneStateModel stateModel = new CallPhoneStateModel(
                                        "callstate", 1, currentCallUUID);
                                Gson gson = new Gson();
                                String text = gson.toJson(stateModel);
                                Log.d(TAG, "发送电话状态："+text);
                                client.send(text);
                            }
                        });

                        Intent intent = new Intent(Intent.ACTION_CALL,
                                Uri.parse("tel:" + eventModel.getPhoneNo()));
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(intent);


                    } else if (eventModel.getMsgType().equals("hangup")) {
                        hangupState = 1;
                        hangup();
                    } else {

                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onClose(int code, String reason, boolean remote) {
                Log.e(TAG, "WebSocket关闭，code："+code+"，reason: "+reason+"，remote: "+remote);
                EventBus.getDefault().post(new WebSocketClientEvent(WebSocketClientEvent.DISCONNECTED));
            }

            @Override
            public void onError(Exception ex) {
                ex.printStackTrace();
                Log.e(TAG, "连接失败");
            }
        };
    }

//    private void forwardAccessibilityActivity() {
//        //开启无障碍
//        Intent i = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
//        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//        startActivity(i);
//    }

    private void hangup() {
        Log.i(TAG, "autoClick() -> 执行挂断");
        //无障碍挂断
        autoClickHangup();

        //系统api挂断
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
//            killPhoneCall();
//        }else {
//            endCallByTelephonyInterface();
//        }

        //飞行模式挂断
//        android.provider.Settings.System.putInt(getContentResolver(),
//                android.provider.Settings.System.AIRPLANE_MODE_ON, 1);
//
//        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
//        intent.putExtra("state", 1);
//        sendBroadcast(new Intent("android.intent.action.AIRPLANE_MODE"));
//        sendBroadcast(intent);
//        android.provider.Settings.System.putInt(getContentResolver(),
//                android.provider.Settings.System.AIRPLANE_MODE_ON, 0);
//
//        intent.putExtra("state", 0);
//        sendBroadcast(new Intent("android.intent.action.AIRPLANE_MODE"));
//        sendBroadcast(intent);
    }

//    private void endCallByTelephonyInterface() {
//        Log.i(TAG, "endCallByTelephonyInterface() -> 执行挂断");
//        // 通过反射，调用隐藏的api
//        Class c = null;
//        Method method = null;
//        //1. 得到隐藏类的Class对象
//        try {
//            c = Class.forName("android.os.ServiceManager");
//        } catch (ClassNotFoundException e) {
//            e.printStackTrace();
//        }
//
//        if (c == null) {
//            return;
//        }
//
//        //2. 得到方法所对用的Method对象
//        try {
//            method = c.getMethod("getService", String.class);
//        } catch (NoSuchMethodException e) {
//            e.printStackTrace();
//        }
//
//        if (method == null) {
//            return;
//        }
//
//        IBinder iBinder = null;
//        //3. 调用方法
//        try {
//            iBinder = (IBinder) method.invoke(null, TELEPHONY_SERVICE);
//        } catch (IllegalAccessException e) {
//            e.printStackTrace();
//        } catch (InvocationTargetException e) {
//            e.printStackTrace();
//        }
//
//        if (iBinder == null) {
//            return;
//        }
//
//        try {
//            //4. 得到接口对象
//            ITelephony telephony = ITelephony.Stub.asInterface(iBinder);
//            //5. 结束通话
//            telephony.endCall();
//            Log.i(TAG, "endCallByTelephonyInterface() -> 执行挂断成功");
//        } catch (RemoteException e) {
//            e.printStackTrace();
//        }
//    }
//
//    private boolean killPhoneCall() {
//        Log.i(TAG, "killPhoneCall() -> 执行挂断");
//        try {
//            tryEndCall();
//
//            TelephonyManager telephonyManager =
//                    (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
//            Class classTelephony = Class.forName(telephonyManager.getClass().getName());
//            Method methodGetITelephony = classTelephony.getDeclaredMethod("getITelephony");
//            methodGetITelephony.setAccessible(true);
//            Object telephonyInterface = methodGetITelephony.invoke(telephonyManager);
//            Class telephonyInterfaceClass =
//                    Class.forName(telephonyInterface.getClass().getName());
//            Method methodEndCall = telephonyInterfaceClass.getDeclaredMethod("endCall");
//            methodEndCall.invoke(telephonyInterface);
//            Log.i(TAG, "killPhoneCall() -> 执行挂断成功");
//        } catch (Exception e) {
//            e.printStackTrace();
//            Log.d(TAG, "hangupPhoneCall: " + e.toString());
//            return false;
//        }
//        return true;
//    }
//
//    private void tryEndCall() {
//        try {
//            TelecomManager telecomManager = (TelecomManager) getSystemService(
//                    Context.TELECOM_SERVICE);
//            if (telecomManager != null) {
//                boolean res = telecomManager.endCall();
//                Log.d(TAG, "tryEndCall: " + res);
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }


    private Notification getNotification(String title, String message) {
        createNotificationChannel();
        //创建一个跳转到活动页面的意图
        Intent clickIntent = new Intent(this, MainActivity.class);
        //clickIntent.putExtra("flag", count);//这里可以传值
        //创建一个用于页面跳转的延迟意图
        PendingIntent pendingIntent;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
            pendingIntent = PendingIntent.getActivity(this, 1012,
                    clickIntent, PendingIntent.FLAG_IMMUTABLE);
        } else {
            pendingIntent = PendingIntent.getActivity(this, 1012,
                    clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        }
        //创建一个通知消息的构造器
        Notification.Builder builder = new Notification.Builder(this);
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            //Android8.0开始必须给每个通知分配对应的渠道
            builder = new Notification.Builder(this, "f_channel_id");
        }
        builder.setContentIntent(pendingIntent)//设置内容的点击意图
                .setAutoCancel(true)//设置是否允许自动清除
                .setSmallIcon(R.mipmap.ic_launcher)//设置状态栏里的小图标
                .setTicker("提示消息来啦")//设置状态栏里面的提示文本
                .setWhen(System.currentTimeMillis())//设置推送时间，格式为"小时：分钟"
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))//设置通知栏里面的大图标
                .setContentTitle(title)//设置通知栏里面的标题文本
                .setContentText(message);//设置通知栏里面的内容文本
        //根据消息构造器创建一个通知对象
        return builder.build();
    }

    @TargetApi(Build.VERSION_CODES.O)
    private void createNotificationChannel() {
        NotificationChannel channel = new NotificationChannel("f_channel_id",
                "CHANNEL_NAME", NotificationManager.IMPORTANCE_HIGH);
        //是否绕过请勿打扰模式
        channel.canBypassDnd();
        //闪光灯
        channel.enableLights(true);
        //锁屏显示通知
        channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
        //闪关灯的灯光颜色
        channel.setLightColor(Color.RED);
        //桌面launcher的消息角标
        channel.canShowBadge();
        //是否允许震动
        channel.enableVibration(true);
        //获取系统通知响铃声音的配置
        channel.getAudioAttributes();
        //获取通知取到组
        channel.getGroup();
        //设置可绕过  请勿打扰模式
        channel.setBypassDnd(true);
        //设置震动模式
        channel.setVibrationPattern(new long[]{100, 100, 200});
        //是否会有灯光
        channel.shouldShowLights();

        mManager.createNotificationChannel(channel);
    }

    /**
     * 1:拨打中,2:通话中,3:无法接通,4:用户挂机,5:APP使用者挂机
     */
    @RequiresApi(api = Build.VERSION_CODES.S)
    private class MyTelephonyCallback extends TelephonyCallback
            implements TelephonyCallback.CallStateListener,
            TelephonyCallback.DataConnectionStateListener {

        @Override
        public void onCallStateChanged(int state) {
            callStateChanged(state);
        }

        @Override
        public void onDataConnectionStateChanged(int state, int networkType) {

        }
    }


    /**
     * 1:拨打中,2:通话中,3:无法接通,4:用户挂机,5:APP使用者挂机
     */
    private class MyPhoneStateListener extends PhoneStateListener {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            callStateChanged(state);
        }
        @Override
        public void onDataConnectionStateChanged(int state) {
            Log.d(TAG, "onDataConnectionStateChanged() -> state="+state);
        }


    }


    /**
     * 1:拨打中,2:通话中,3:无法接通,4:用户挂机,5:APP使用者挂机
     */
    private void callStateChanged(int state) {
        Log.d(TAG, "onCallStateChanged() -> state="+state);
        switch (state) {
            case TelephonyManager.CALL_STATE_IDLE:
                Log.d(TAG, "电话状态 -> 空闲");
//                    stopRecording();
//
//                if (oldFileArray != null && oldFileArray.length != getRecordFileArray().length) {
//                    uploadFileToServer();
//                }

//                if (fileCheckThread != null) {
//                    fileCheckThread.setFlag(false);
//
//                    if (fileCheckThread.isFileChanged()) {
//                        uploadFileToServer();
//                    } else {
//                        //挂断了录音文件都没有发生变化，那就是无法接通
//                        executorService.execute(new Runnable() {
//                            @Override
//                            public void run() {
////                        CallPhoneStateModel stateModel = new CallPhoneStateModel("callstate",
////                                3, "1111-2222-3333");
//                                CallPhoneStateModel stateModel = new CallPhoneStateModel(
//                                        "callstate", 3, currentCallUUID);
//                                Gson gson = new Gson();
//                                String text = gson.toJson(stateModel);
//                                Log.d(TAG, "发送电话状态："+text);
//                                client.send(text);
//
//                                hangupState = 0;
//                            }
//                        });
//                    }
//                }
//
                sendHangUpState();

                break;
            case TelephonyManager.CALL_STATE_RINGING:
                Log.d(TAG, "电话状态 -> 来电响铃");

                break;
            case TelephonyManager.CALL_STATE_OFFHOOK:
                String status = previousStats == 1 ? "拨打" : "接听";
                Log.d(TAG, "电话状态 -> " + status);

                callTime = Calendar.getInstance().getTimeInMillis();
                String callDate = dateFormat.format(new Date(callTime));
                Log.d(TAG, "callTime="+callTime);
                Log.d(TAG, "callDate="+callDate);


                // 开始录音
//                    new Thread(new Runnable() {
//                        @Override
//                        public void run() {
//                            SystemClock.sleep(2000);
//                            startRecording(phoneNumber);
//                        }
//                    }).start();
                break;
            default:
                Log.d(TAG, "电话状态 -> 未知状态");
                break;
        }
    }


    private void startRecording(String incomingNumber) {
        if (recorder != null && isRecording) {
            Log.d(TAG, "正在录音...");
            return;
        }

        AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        audioManager.setMode(AudioManager.MODE_IN_CALL);
        audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, maxVolume, 0);
        try {
            Log.d(TAG, "启动录音");
            isRecording = true;
            recorder = new MediaRecorder();

//            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
//                recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
//            } else {
//                recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
//            }
//            recorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS);
//            recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

            recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

            File out = new File(dirPath);
            if (!out.exists()) {
                out.mkdirs();
            }

            recorder.setOutputFile(dirPath + getFileName(incomingNumber));
            recorder.prepare();
            recorder.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void stopRecording() {
        if (recorder != null && isRecording) {
            Log.d(TAG, "停止录音");
            try {
                isRecording = false;
                recorder.stop();
                recorder.reset();
                recorder.release();
                recorder = null;
            }catch (Exception e) {
                e.printStackTrace();
            }
            uploadFile();
        }
    }

    private File[] getRecordFileArray(){
        File parent = Environment.getExternalStorageDirectory();
        File child;

        //获取手机厂商
        if (RomUtils.isHuawei()) {
            child = new File(parent, "record");
            if (!child.exists()) {
                child = new File(parent, "Sounds/CallRecord");
            }
        } else if (RomUtils.isXiaomi()) {
            child = new File(parent, "MIUI/sound_recorder/call_rec");
        } else if (RomUtils.isMeizu()) {
            child = new File(parent, "Recorder");
        } else if (RomUtils.isOppo()) {
            child = new File(parent, "Recordings/Call Recordings");
            if (!child.exists()) {
                child = new File(parent, "Recordings");
            }
        } else if (RomUtils.isVivo()) {
            child = new File(parent, "Record/Call");
        } else if (RomUtils.isSamsung()) {
            child = new File(parent, "Sounds");
        } else {
            child = new File(parent, "");
        }

        if (!child.exists()) {
            return new File[]{};
        }

        return child.listFiles();

    }

    private static boolean matchFileName(String name) {
        try {
            if (name.toLowerCase().endsWith(".mp3".toLowerCase())) {
                return true;
            } else if (name.toLowerCase().endsWith(".wav".toLowerCase())) {
                return true;
            } else if (name.toLowerCase().endsWith(".3gp".toLowerCase())) {
                return true;
            }
//            else if (name.toLowerCase().endsWith(".mp4".toLowerCase())) {
//                return true;
//            }
            else if (name.toLowerCase().endsWith(".amr".toLowerCase())) {
                return true;
            } else if (name.toLowerCase().endsWith(".3gpp".toLowerCase())) {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     *   最后的修改时间是:1689409031000
     *   最后的修改时间是:2023-07-15 16:17:11
     *   callTime=1689409022389
     *     return Math.abs(callTime - file.lastModified()) < 5 * 1000;
     * @param file
     * @return
     */
    private boolean checkTime(File file) {
        return Math.abs(callTime - file.lastModified()) < 50 * 1000;
    }


    private File getRecordFile() {
        File parent = Environment.getExternalStorageDirectory();
        File child;

        //获取手机厂商
        if (RomUtils.isHuawei()) {
            child = new File(parent, "record");
            if (!child.exists()) {
                child = new File(parent, "Sounds/CallRecord");
            }
        } else if (RomUtils.isXiaomi()) {
            child = new File(parent, "MIUI/sound_recorder/call_rec");
        } else if (RomUtils.isMeizu()) {
            child = new File(parent, "Recorder");
        } else if (RomUtils.isOppo()) {
            child = new File(parent, "Recordings/Call Recordings");
            if (!child.exists()) {
                child = new File(parent, "Recordings");
            }
        } else if (RomUtils.isVivo()) {
            child = new File(parent, "Record/Call");
        } else if (RomUtils.isSamsung()) {
            child = new File(parent, "Sounds");
        } else {
            child = new File(parent, "");
        }

        if (!child.exists()) {
            Log.d(TAG, "录音文件夹不存在");
            return null;
        }

        File[] files = child.listFiles();
        if (files == null || files.length == 0) {
            Log.d(TAG, "录音文件夹下面录音文件不存在");
            return null;
        }

        if (files.length == 1) {
            return files[0];
        }

        ArrayList<File> fileArrayList = new ArrayList<>();
        Collections.addAll(fileArrayList, files);
        Collections.sort(fileArrayList, new Comparator<File>() {
            @Override
            public int compare(File file1, File file2) {
                long time1 = file1.lastModified();
                long time2 = file2.lastModified();

                // 根据时间进行比较
                if (time1 < time2) {
                    return -1;
                } else if (time1 > time2) {
                    return 1;
                } else {
                    return 0;
                }
            }
        });

        return fileArrayList.get(fileArrayList.size() - 1);
    }

    private void uploadFileToServer() {
        File file1 = getRecordFile();
//        File file1 = new File("/storage/emulated/0/MIUI/sound_recorder/call_rec/10010(10010)_20230715152415.mp3");
        if (file1 == null) {
            Log.d(TAG, "没有找到匹配的录音文件");
            return;
        }

        final String path = file1.getAbsolutePath();
        Log.d(TAG, "找到匹配的录音文件:" + path);
        if (NetWorkUtils.isNetworkConnected(getApplicationContext())) {

            Map<String, String> map = new HashMap<String, String>();
            map.put("cid", String.valueOf(cid));
            map.put("code", code);
            final String url = Constants.SERVER_URL + "/api/uploadFile";

            try {
                OkHttpUtils.post()
                        .url(url)
                        .addFile("file", file1.getName(), file1)//
                        .params(map).build()
                        .execute(new StringCallback() {
                            @Override
                            public void onError(Request request, Exception e) {
                                Log.e(TAG, "上传失败 response=" + e.toString());
                                saveUnUploadFIles(path);
                            }

                            @Override
                            public void onResponse(String response) {
                                Log.e(TAG, "上传成功 response=" + response);
                            }

                        });
            }catch (Exception e){
                e.printStackTrace();
            }
        } else {
            saveUnUploadFIles(path);
        }
    }


    /**
     * 当录音结束后，自动上传录音文件。
     */
    private void uploadFile() {
        ZipUtils.zipFile(dirPath + currentFile, dirPath + currentFile + ".zip");
        if (NetWorkUtils.isNetworkConnected(getApplicationContext())) {
            //上传文件
//            OkHttpUtils.postFile();
        } else {
            saveUnUploadFIles(dirPath + currentFile + ".zip");
        }
    }

    /**
     * 保存未上传的录音文件
     * @param file 未上传的录音文件路径
     */
    private void saveUnUploadFIles(String file) {
        String newFile = cid + "-" + code + "-" + file;
        Log.i(TAG, "保存未上传的录音文件："+newFile);
        String files = unUploadFileSharedPreferences.getString("unUploadFile", "");
        if (files.equals("")) {
            files = newFile;
        } else {
            StringBuilder sb = new StringBuilder(files);
            files = sb.append(";").append(newFile).toString();
        }
        unUploadFileSharedPreferences.edit().putString("unUploadFile", files).apply();
    }

    /**
     * 上传因为网络或者其他原因，暂未上传或者上传失败的文件，重新上传
     */
    public void uploadUnUploadedFiles() {
        //获取当前还未上传的文件，并把这些文件上传
        String files = unUploadFileSharedPreferences.getString("unUploadFile", "");
        unUploadFileSharedPreferences.edit().putString("unUploadFile", "").apply();
        if (files.equals("")) {
            return;
        }
        String[] fileArry = files.split(";");
        for (String file : fileArry) {
            upload(file);
        }
    }

    /**
     * 文件上传
     */
    public void upload(String data) {
        String[] fileArry = null;
        try {
            fileArry = data.split("-");
        }catch (Exception e){
            e.printStackTrace();
        }
        if (fileArry == null || fileArry.length == 0) {
            return;
        }
        String cid = fileArry[0];
        String code = fileArry[1];
        String path = fileArry[2];

        File file1 = new File(path);
        if (!file1.exists()) {
            //文件不存在
            return;
        }
        if (!NetWorkUtils.isNetworkConnected(getApplicationContext())) {
            saveUnUploadFIles(data);
            return;
        }

        Map<String, String> map = new HashMap<String, String>();
        map.put("cid", cid);
        map.put("code", code);
        final String url = Constants.SERVER_URL + "/api/uploadFile";
        try {
            OkHttpUtils.post()//
                    .addFile("file", file1.getName(), file1)//
                    .url(url)//
                    .params(map).build()//
                    .execute(new StringCallback() {
                        @Override
                        public void onError(Request request, Exception e) {
                            Log.e(TAG, "上传失败 response=" + e.toString());
                            saveUnUploadFIles(data);
                        }

                        @Override
                        public void onResponse(String response) {
                            Log.e(TAG, "上传成功 response=" + response);
                        }

                    });
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 获取录音文件的名称
     *
     * @param incomingNumber 通话号码
     * @return 获取录音文件的名称
     */
    private String getFileName(String incomingNumber) {
        Date date = new Date(System.currentTimeMillis());
//        currentFile = incomingNumber + " " + dateFormat.format(date) + ".aac";
        currentFile = incomingNumber + " " + dateFormat.format(date) + ".3gp";
        return currentFile;
    }

    /**
     * 拨号广播接收器，并获取拨号号码
     */
    public class OutCallReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            currentCallNum = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
            if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
                Log.d(TAG, "拨打电话：" + currentCallNum);
                previousStats = 1;
            } else {
                Log.d(TAG, "接听电话：" + currentCallNum);
                previousStats = 2;
            }
        }
    }

    /**
     * 网络状态change广播接收器
     */
    public class NetworkConnectChangedReceiver extends BroadcastReceiver {
        private static final String TAG = "NetworkStatus";

        @Override
        public void onReceive(Context context, Intent intent) {
            if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
                ConnectivityManager manager = (ConnectivityManager) context
                        .getSystemService(Context.CONNECTIVITY_SERVICE);
                NetworkInfo activeNetwork = manager.getActiveNetworkInfo();
                if (activeNetwork != null) { // connected to the internet
                    if (activeNetwork.isConnected()) {
                        //当前网络可用
                        if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
                            // connected to wifi
                            Log.e(TAG, "当前WiFi连接可用 ");
                        } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
                            // connected to the mobile provider's data plan
                            Log.e(TAG, "当前移动网络连接可用 ");
                        }
//                        uploadUnUploadedFiles();
                    } else {
                        Log.e(TAG, "当前没有网络连接，请确保你已经打开网络 ");
                    }

                } else { // not connected to the internet
                    Log.e(TAG, "当前没有网络连接，请确保你已经打开网络 ");
                }


            }
        }
    }

}